ObjectKit= new function ()
{
        /**
         * @private
         * A reference to the Function protoype
         * @type Object
         */
    var F= Function.prototype
    
        /**
         * @private
         * A reference to the Array slice method
         * @type Function
         */
    ,   S= Array.prototype.slice
    
        /**
         * @private
         * The anonymous keyword
         * @type String
         */
    ,   A= 'anonymous'
    
        /**
         * @private
         * Internal flag variable used to manage ObjectKits preventOverride
         * behaviour.
         * @type {Boolean}
         * @see Function.prototype.implement.preventOverride
         * @see ObjectKit.setPreventOverride
         */
    ,   P= true;
     
    /**
     * Implement any number of properties on a constructors prototype by 
     * supplying any number of objects and named functions. Objects
     * are shallow copied to the constructors prototype, while named functions
     * are first reflected before being added to the constructors prototype.

     * @param {...Object}        Any number of objects or named functions
     * @return {Function}        A reference to the modified prototypes constructor
     * 
     * @see #implementStatic
     * @see #implement.preventOverride
     */
    F.implement= function () 
    {
        this.implementStatic.apply(this.prototype, arguments);
        return this;  
    };

    /**
     * Implement any number of properties direclty on a constructor, by 
     * supplying any number of objects and named functions. Objects
     * are shallow copied to the constructor, while named functions
     * are first reflected before being added to the constructor.
     * 
     * 
     * @param {...Object}        Any number of objects or named functions
     * @return {Function}        A reference to the modified constructor
     */
    F.implementStatic= function () 
    {
        var trait= null
        ,   n= arguments.length
        ,   i= 0
        ,   canOverwrite= !F.implement.preventOverride
        ,   accessor;
        
        for (; i < n; i++) 
        {
            trait= arguments[i];
            if (null == trait)
                continue;

            if ('function' === typeof trait) 
            {
                accessor= trait.getName(); 
                
                if (A !== accessor 
                && 'constructor' !== accessor
                && (canOverwrite || !(accessor in this)))
                    this[accessor]= trait; 
            }
            else for (accessor in trait) 
            {
                if (canOverwrite || !(accessor in this))
                    this[accessor]= trait[accessor]; // what about hasOwnProperty? // what about parent and prototype?
            }
        }
        
        // reset to the default value as determined by ObjectKit.setPreventOverride
        F.implement.preventOverride= P;
        return this;
    };

    /**
     * A flag variable that you can use to prevent or allow the overriding
     * of properties defined on a constructors prototype. Note that after
     * each invocation of #implement or #implementStatic, that this value is
     * set to true or false depending on whether or not override protection
     * is on or off by default.
     * 
     * @type {Boolean}
     * @see #implement
     * @see #implementStatic
     * @see ObjectKit.setPreventOverride
     */
    F.implement.preventOverride= true;

    /**
     * Determine a functions name. The work 'anonymous' is returned for
     * functions that have not been defined with a name.
     * 
     * @example alert(Date.getName()); // 'Date'
     * 
     * @return {String}    The functions name.
     */
    F.getName= ('name' in F) ? function () 
    {
        // use the non-standard Function.prototype.name property
        var name= this.name;
        // normalize the result for 'anonymous' functions
        return ('' === name || 'Empty' === name) ? A : name;
    }
    : function () 
    {
        var name= this.name;
        if (name)  // if the functions name has been cached
            return name; // return it
        
        // else decompile and parse the function to get its name    
        name= String(this).match(/^function\s([\w|$]+)/);
        // then cache it before returning
	    return this.name= String(name ? name[1] : A);
    }
    
    // implement remaining methods on Function.prototype
    Function.implement
    (
        {
            /**
             * Extend one constructors prototype by another.
             * 
             * @param {Function} Super   The constructor to inherit from.
             * @return {Function}        A reference to the extended constructor.
             */
            inherit: function (Super) 
            {
                if ('function' !== typeof Super || this === Super)
                    throw new TypeError('Inheritance error.');
                    
                function Intermediary () {;};
                Intermediary.prototype= Super.prototype;

                this.prototype= new Intermediary;
                this.prototype.constructor= this;
                this.prototype.parent= Super.prototype;
                return this;
            }
            
            /**
             * Preset a function with an execution scope and any number of
             * arguments. Any additional arguments supplied to the bound
             * function will be concatenated to the preset arguments provided 
             * to this method.
             * 
             * @example
             *     <code>
             *         <pre>
             *         
             *             var object=
             *             {
             *                 value: 'localValue'
             *             ,   getValue: function () 
             *                 {
             *                     return this.value;
             *                 }
             *                 
             *             ,   setValue: function (value)
             *                 {
             *                     this.value= value;
             *                 }
             *             };
             *             
             *             window.value= 'globalValue';
             *         
             *             alert(object.getValue()); // alerts 'localValue';
             *         
             *             var getValue= object.getValue;
             *             
             *             alert(getValue()); // alerts 'globalValue';
             *             
             *             getValue= getValue.bind(object);
             *             
             *             alert(getValue()); // alerts 'localValue';
             *         
             *         </pre>
             *     </code>
             * 
             * @param {Object} executionScope
             * @param {...Object} presetArgs
             * @return {Function}
             */           
       ,    bind: function (executionScope) 
            {
                var method= this
                ,   presetArgs;
        
                if (2 > arguments.length) return function () 
                {
                     return method.apply(executionScope, arguments);
                }

                presetArgs= S.call(arguments, 1);
                return function () 
                {
                    return method.apply(executionScope, presetArgs.concat(arguments));
                };
            } 
            
            /**
             * Determine if an object is of a particular type or not, eliding
             * the distinction between primitive and object values.
             *     
             * @param {Object} value    Any value.
             * @return {Boolean}        
             * @see #is
             */
        ,   type: function (value) 
            {
                // little known feature of JavaScript- passing a primitive
                // value to the Object constructor returns its object 
                // counterpart, while passing an object to the Object
                // constructor simply returns that object! This is how the
                // the #type method elides the distinction between primitive
                // strings, numbers and booleans and instances of String, Number
                // and Boolean. Note that passing null or undefined to Object
                // in this way returns a new object, thus the gaurd clause
                // returning false for undefined and null
                return null == value ? false : Object(value) instanceof this;   
            }
            
            /**
             * Determine iff an object was constructed by a particular 
             * constructor or not.
             * 
             * @param {Object} value            Any value.
             * @return {Boolean}
             * @see #type
             */
        ,   is: function (value) 
            {
                // Another lesser known feature of JavaScript is that the
                // interpreter will automagically transform a primitive value
                // to its object counterpart if the property accessor '.' is
                // used against it. The exceptions to the rule are null and
                // undefined, thus the gaurd clause.
                return null == value ? false : value.constructor === this;
            }
            
            /**
             * Defer the execution of a function to later point in time, optionally
             * supplying an execution scope and any number of arguments to use
             * during execution.
             * 
             * The returned object has the following properties and methods which
             * can be used to further control the execution of the deferred
             * function.
             * 
             * @param {Number} interval            The milisecond interval to 
             * @param {Object} executionScope      Optional. The object scope
             * @param {...Object} presetArgs       Optional. Any nuber of arguments.
             * @return {Object}
             * @see #bind
             */
        ,   defer: function (interval, executionScope) 
            {
                // we could have used the closure object pattern here, but this
                // is the cheapest way of implementing defer
                var method= this
                ,   timeoutId
                ,   presetArgs= S.call(arguments, 2)
                ,   deferred= 
                    {
                        hasExecuted: false
                    ,   createdOn: Number(new Date())
                    ,   executedOn: -1
                    ,   interval: interval
                    ,   dispose: function () 
                        {
                            clearTimeout(timeoutId);
                            this.execute= method= null;
                        }
                    ,   execute: function () 
                        {
                            deferred.hasExecuted= true;
                            deferred.executedOn= Number(new Date())
                            try 
                            {
                                deferred.result= method.apply(executionScope, presetArgs);
                            }
                            catch (thrown) 
                            {
                                deferred.fault= thrown;
                            }
                            finally 
                            {
                                 deferred.dispose();
                                 if ('function' === typeof deferred.onExecute)
                                    deferred.onExecute(null == deferred.fault);
                            }
                        }
                    }
                ;
                
                timeoutId= setTimeout(deferred.execute, interval);
                return deferred;
            }
        }
    );
    
    this.constructor.implement
    (
        {
            /**
             * Enable or disable ObjectKits default override protection behaviour.
             * After each invocation of #implement or #implementStatic, the
             * value of #implement.preventOverride will be reset to the value
             * provided here.
             * 
             * @param {Boolean} value       True to enable, false to disable.
             * @return {void}
             * @see #willPreventOverride
             */
            setPreventOverride: function (value)
            {
                return F.implement.preventOverride= P= !!value;
            }

            /**
             * Determine if ObjectKit will prevent or allow overriding of 
             * properties by default.
             * 
             * @return {Boolean}
             * @see #setPreventOverride
             */
        ,   willPreventOverride: function ()
            {
                return P;
            }
        }
    );
    
    // overriding methods and properties is enabled by default
    this.setPreventOverride(false);
}
